package com.zx.练习题.demo;

import cn.hutool.core.lang.Snowflake;

public class HashShardingDb {

    private static Snowflake sf = new Snowflake(1L, 1L);

    public static void main(String[] args) {
        String month = "202001";
        String day = "20200101";
        String muinte = "2020-01-01 00:01";

        System.out.println(hash(month));
        System.out.println(hash(day));
        System.out.println(hash(muinte));
        System.out.println("**********");
        getId(2);

        for (int i = 0; i < 5; i++) {
            System.out.println("$$$$$$$$$$$");
            //用户id(随机一个用户id)
            long userId = sf.nextId();
            //因子
            int yinzi = 3;
            //表的数量
            int tableNum = (int) Math.pow(2D, (double) yinzi);

            long jiyin = getJiyin(userId, yinzi);
            long table = getTable(userId, tableNum);
            System.out.println("用户id的基因：id=" + userId + ", 基因=" + jiyin);
            System.out.println("使用用户id获得分表后缀：" + table);

            for (int j = 0; j < 5; j++) {
                long newId = getId(jiyin);
                long newTable = getTable(table, tableNum);
                System.out.println("使用基因获得普通id：" + newId + ", table=" + newTable);
            }
        }


    }

    public static int hash(Object key) {
        int h = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        return (10 - 1) & h;
    }


    public static long getTable(long num, long tableNum) {
        return num % tableNum;
    }

    public static long getJiyin(long userId, int yinzi) {
        long res = 0L;

        for (int i = 63; i < 63 - yinzi; i++) {
            res = res | userId >> i;
        }

        return res;
    }

    public static long getId(long jiyin) {
        //System.out.println(Long.toBinaryString(i));
        long id = sf.nextId();
        //System.out.println(Long.toBinaryString(id));
        id = id >> jiyin;
        //System.out.println(Long.toBinaryString(id));
        id = id | jiyin;
        //System.out.println(Long.toBinaryString(id));
        return id;
    }

}
